home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / 32QUERY.PAK / ENGINE.C < prev    next >
C/C++ Source or Header  |  1997-05-06  |  17KB  |  540 lines

  1. // BDE32 3.x - (C) Copyright 1996 by Borland International
  2.  
  3. #include "query.h"
  4.  
  5. //===============================================================
  6. //  Name:   QueryGetStandardConnection(void)
  7. //
  8. //  Input:  None
  9. //
  10. //  Return: returns handle to standard database if successful, 
  11. //          zero otherwise
  12. //
  13. //  Description:
  14. //          Opens a standard (Paradox & dBase) database.
  15. //================================================================
  16. hDBIDb
  17. QueryGetStandardConnection(void)
  18. {
  19.     hDBIDb   hDb;   // Handle to the database
  20.  
  21.     // Open the standard database
  22.     DBIErr(DbiOpenDatabase(NULL, NULL, dbiREADWRITE, dbiOPENSHARED,
  23.                            NULL, 0, NULL, NULL, &hDb));
  24.  
  25.     // Point to the sample tables
  26.     DBIErr(DbiSetDirectory(hDb, szTblDirectory));
  27.  
  28.     return hDb;
  29. }
  30.  
  31. //===============================================================
  32. //  Name:   QueryQExec(hDb, eQryLang, szQuery, szOutputErrorString,
  33. //                     phCur)
  34. //
  35. //  Input:  hDb         - Handle to the database
  36. //          eQryLang    - Query language (SQL or QBE)
  37. //          szQuery     - Query string
  38. //          phCur       - Pointer to a cursor handle to the result
  39. //                        set
  40. //
  41. //  Return: DBIERR_NONE if successful, otherwise error encountered
  42. //
  43. //  Description:
  44. //          Prepares and executes an SQL or QBE query.          
  45. //================================================================
  46. DBIResult
  47. QueryQExec (hDBIDb hDb, DBIQryLang eQryLang, pCHAR szQuery,
  48.             pCHAR szOutputErrorString, phDBICur phCur)
  49. {
  50.     DBIResult   rslt;   // Return Value from Engine functions
  51.     hDBIStmt    hStmt;  // Handle to the returned Statment (query)
  52.  
  53.     // Set up the query.
  54.     if ((rslt = DbiQAlloc(hDb, eQryLang, &hStmt))
  55.         != DBIERR_NONE)
  56.     {
  57.         GetErrorInformation(szOutputErrorString);
  58.         return rslt;
  59.     }
  60.     if ((rslt = DbiQPrepare(hStmt, szQuery))
  61.         != DBIERR_NONE)
  62.     {
  63.         GetErrorInformation(szOutputErrorString);
  64.         return rslt;
  65.     }
  66.  
  67.     // Execute the query.
  68.     rslt = DbiQExec(hStmt, phCur);
  69.  
  70.     // Check if query failed.
  71.     if (rslt != DBIERR_NONE)
  72.     {
  73.         GetErrorInformation(szOutputErrorString);
  74.         DBIErr(DbiQFree(&hStmt));
  75.         return rslt;
  76.     }
  77.  
  78.     if (SetMaxRows == TRUE)
  79.     {
  80.         if ((rslt = DbiSetProp(*phCur, curMAXROWS, MaxRows)) != DBIERR_NONE)
  81.         {
  82.             GetErrorInformation(szOutputErrorString);
  83.             return rslt;
  84.         }
  85.     }
  86.  
  87.     // Free memory associated with the query.
  88.     DBIErr(DbiQFree(&hStmt));
  89.  
  90.     return rslt;
  91. }
  92.  
  93. //===============================================================
  94. //  Name:   QueryDBIInit(void)
  95. //
  96. //  Input:  None.
  97. //
  98. //  Return: Result of attempt to use DbiInit.
  99. //
  100. //  Description:
  101. //          Calls DbiInit, notifies user if problem.
  102. //================================================================
  103. DBIResult
  104. QueryDbiInit (void)
  105. {
  106.     DBIResult   rslt;   // Return value from IDAPI functions.
  107.     pCHAR       pszMessage;
  108.  
  109.     // Initialize IDAPI.
  110.     if (DBIErr(DbiInit(NULL)) != DBIERR_NONE)
  111.     {
  112.          return GlobalDBIErr;
  113.     }
  114.  
  115.     // Enable trace info if the debugging layer is enabled.
  116.     DbiDebugLayerOptions(DEBUGON | OUTPUTTOFILE, "QUERY.INF");
  117.  
  118.     // Set the directory to use for temporary files.
  119.     rslt = DbiSetPrivateDir(szPrivDirectory);
  120.     if (rslt == DBIERR_DIRBUSY)
  121.     {
  122.         pszMessage = (pCHAR)malloc(((DBIMAXMSGLEN * 3) + 1) * sizeof(char));
  123.         if (pszMessage)
  124.         {
  125.             sprintf(pszMessage, "Directory is busy. Make certain no .LCK"
  126.                     " files exist in the %s directory and that the IDAPI"
  127.                     " DLLs are unloaded (Reboot Windows).",
  128.                     szPrivDirectory);
  129.             MessageBox(NULL, pszMessage, "SetPrivateDir Error",
  130.                        MB_OK | MB_ICONHAND);
  131.             free(pszMessage);
  132.         }
  133.         return rslt;
  134.     }
  135.  
  136.     return DBIERR_NONE;
  137. }
  138.  
  139. //===============================================================
  140. //  Name:   QueryDbiExit(void)
  141. //
  142. //  Input:  None
  143. //
  144. //  Return: Result of attempt to use DbiExit.
  145. //
  146. //  Descrption:
  147. //          Calls DbiExit, notifies user if problem.          
  148. //================================================================
  149. DBIResult
  150. QueryDbiExit (void)
  151. {
  152.     // Turn off debugging (if Debug layer DLL selected).
  153.     DbiDebugLayerOptions(0, NULL);
  154.  
  155.     // Close the engine.
  156.     return DBIErr(DbiExit());
  157. }
  158.  
  159. //===============================================================
  160. //  Name:   QueryDbiCloseDatabase(phDb);
  161. //
  162. //  Input:  phDb -- pointer to database handle to close
  163. //
  164. //  Return: None
  165. //
  166. //  Description:
  167. //          Calls DbiCloseDatabase, displays error message if
  168. //          DBI error is encountered and bDisplayError is TRUE.          
  169. //================================================================
  170. void
  171. QueryDbiCloseDatabase (phDBIDb phDb)
  172. {
  173.     // Close the standard database.
  174.     DBIErr(DbiCloseDatabase(phDb));
  175. }
  176.  
  177. //===============================================================
  178. //  Name:   QueryResetConnectDialog(hWnd, dbarray, iSelected);
  179. //
  180. //  Input:  hWnd        - Handle to the connect dialog
  181. //          dbarray     - The array of database handles, which is used
  182. //                        to fill the connection listbox
  183. //          iSelected   - Currently selected database
  184. //
  185. //  Return: None
  186. //
  187. //  Description:
  188. //          Resets the "connect to the database" dialog on 
  189. //          during initialization or based on the current 
  190. //          driver selected.
  191. //================================================================
  192. void
  193. QueryResetConnectDialog (HWND hWnd, const DBStructArray dbarray,
  194.                          const int iSelected)
  195. {
  196.     hDBICur     hList;
  197.     DBDesc      DbData;
  198.     int         i;
  199.  
  200.     // Reset default connection static control.
  201.     SendDlgItemMessage(hWnd, IDS_SELECTED_CONNECTION,
  202.                        WM_SETTEXT, 0,
  203.                        (LPARAM) dbarray[iSelected].szDatabaseName);
  204.  
  205.     // Reset alias listbox.
  206.     if (DBIErr(DbiOpenDatabaseList(&hList)) == DBIERR_NONE)
  207.     {
  208.         while (DbiGetNextRecord(hList, dbiNOLOCK, (pBYTE) &DbData,
  209.                                 NULL) == DBIERR_NONE)
  210.         {
  211.             SendDlgItemMessage(hWnd, IDC_LB_ALIASES, LB_INSERTSTRING,
  212.                                0, (LPARAM) DbData.szName);
  213.         }
  214.         DBIErr(DbiCloseCursor(&hList));
  215.     }
  216.  
  217.     // Reset connections listbox.
  218.     SendDlgItemMessage(hWnd, IDC_LB_CONNECTIONS, LB_RESETCONTENT, 0, 0);
  219.     for (i = 0; i < MAX_DATABASE_HANDLES; i++)
  220.     {
  221.         if (dbarray[i].hdb == 0)
  222.         {
  223.             break;
  224.         }
  225.         SendDlgItemMessage(hWnd, IDC_LB_CONNECTIONS, LB_INSERTSTRING, i, 
  226.                           (LPARAM) dbarray[i].szDatabaseName);
  227.     }                                          
  228. }
  229.  
  230. //===============================================================
  231. //  Name:   QueryConnectToDatabase(hWnd);
  232. //
  233. //  Input:  hWnd - Handle to the connect dialog
  234. //
  235. //  Return: Handle to the database, or zero if connection cannot
  236. //          be established
  237. //
  238. //  Description:
  239. //          Try to connect to a database based on the data
  240. //          selected in the connection dialog box; display 
  241. //          result in the static control.
  242. //================================================================
  243. hDBIDb
  244. QueryConnectToDatabase (HWND hWnd)
  245. {
  246.     hDBIDb      hDb;
  247.     WORD        ListIndex;
  248.     pCHAR       Msg;
  249.     pCHAR       Driver;
  250.     pCHAR       Alias;
  251.     pCHAR       Password;
  252.     DBIErrInfo  ErrInfo;
  253.  
  254.     // Init the strings. 
  255.     Alias = (pCHAR)malloc(DBIMAXSCFLDLEN);
  256.     Driver = (pCHAR)malloc(DBIMAXSCFLDLEN);
  257.     Password = (pCHAR)malloc(DBIMAXSCFLDLEN);
  258.     Msg = (pCHAR)malloc((DBIMAXMSGLEN + 1) * 4);
  259.     if ((Alias == NULL) || (Driver == NULL) || (Password == NULL) ||
  260.         (Msg == NULL))
  261.     {
  262.         hDb = 0;
  263.         if (Msg) free(Msg);
  264.         if (Alias) free(Alias);
  265.         if (Driver) free(Driver);
  266.         if (Password) free(Password);
  267.         sprintf(Msg, "Unable to connect: Out of memory!");
  268.         SendDlgItemMessage(hWnd, IDC_STATIC_STATUS, WM_SETTEXT, 0,
  269.                            (LPARAM) Msg);
  270.         MessageBeep(MB_ICONEXCLAMATION);
  271.         return hDb;
  272.     }
  273.  
  274.     Alias[0] = '\0';
  275.     Driver[0] = '\0';
  276.     Password[0] = '\0';
  277.  
  278.     // SQL database needs the alias & password. 
  279.     ListIndex = (WORD)SendDlgItemMessage(hWnd, IDC_LB_ALIASES, LB_GETCURSEL, 0,
  280.                                          0);
  281.     SendDlgItemMessage(hWnd, IDC_LB_ALIASES, LB_GETTEXT, (WPARAM)
  282.                        ListIndex, (LPARAM) Alias);
  283.     SendDlgItemMessage(hWnd, IDC_EDIT_PASSWORD, WM_GETTEXT, 80,
  284.                        (LPARAM) Password);
  285.  
  286.     // Try to open the database. 
  287.     hDb = 0;
  288.     SendDlgItemMessage(hWnd, IDL_RESULTS, LB_RESETCONTENT, 0, 0);
  289.  
  290.     // Establish connection to the database
  291.     if ((DbiOpenDatabase(Alias, Driver, dbiREADWRITE, dbiOPENSHARED,
  292.                          Password, 0, NULL, NULL, &hDb))
  293.         == DBIERR_NONE)
  294.     {
  295.         SendDlgItemMessage(hWnd, IDC_STATIC_STATUS, WM_SETTEXT, 0,
  296.                            (LPARAM) "Connection is available!");
  297.     }
  298.     else
  299.     {
  300.         // Failed to connect
  301.         hDb = 0;
  302.         DbiGetErrorInfo(TRUE, &ErrInfo);
  303.  
  304.         sprintf(Msg, "Unable to connect:  Cat:Code = [%xh:%xh]"
  305.                 "\r\n    %s"
  306.                 "\r\n    %s"
  307.                 "\r\n    %s"
  308.                 "\r\n    %s"
  309.                 "\r\n    %s",
  310.                 ErrCat(ErrInfo.iError), ErrCode(ErrInfo.iError),
  311.                 ErrInfo.szErrCode, ErrInfo.szContext1, ErrInfo.szContext2,
  312.                 ErrInfo.szContext3, ErrInfo.szContext4);
  313.         SendDlgItemMessage(hWnd, IDC_STATIC_STATUS, WM_SETTEXT, 0,
  314.                            (LPARAM) Msg);
  315.         MessageBeep(MB_ICONEXCLAMATION);
  316.     }
  317.  
  318.     // Clean up.
  319.     
  320.     free(Msg);
  321.     free(Alias);
  322.     free(Driver);
  323.     free(Password);
  324.  
  325.     return hDb;
  326. }
  327.  
  328. //===============================================================
  329. //  Name:   QuerySaveResultSet(hCur, hDb, szFileName);
  330. //
  331. //  Input:  hCur        - Handle to source cursor
  332. //          hDb         - Handle to database
  333. //          szFileName  - Filename to use in saving the result set
  334. //
  335. //  Return: TRUE if result set was saved
  336. //          FALSE otherwise
  337. //
  338. //  Description:
  339. //          Saves the result set of the last successful query.
  340. //          IMPORTANT NOTE:  since this function is called from the
  341. //          common dialog box, and is only called after the user
  342. //          has confirmed that an existing file should be
  343. //          over-written, if the file exists this function
  344. //          deletes the file before saving it.
  345. //================================================================
  346. BOOL
  347. QuerySaveResultSet (hDBICur hCur, hDBIDb hDb, char* szFileName)
  348. {           
  349.     OFSTRUCT    ofstruct;
  350.     BATTblDesc  BatTblDesc = {
  351.                                NULL,
  352.                                "",
  353.                                szPARADOX,
  354.                                { NULL },
  355.                                { NULL }
  356.                              };
  357.  
  358.     // Delete the file if it exists.
  359.     OpenFile(szFileName, &ofstruct, OF_DELETE);
  360.     
  361.     BatTblDesc.hDb = hDb;   
  362.     strcpy(BatTblDesc.szTblName, szFileName);
  363.  
  364.     DBIErr(DbiSetToBegin(hCur));
  365.  
  366.     // Save the result set to the hard disk.                                
  367.     if (DBIErr(DbiBatchMove(NULL, hCur, &BatTblDesc, NULL, batCOPY, NULL,
  368.                             NULL, NULL, NULL, NULL, NULL, NULL,
  369.                             NULL, NULL, NULL, NULL, TRUE, TRUE,
  370.                             NULL, TRUE)) != DBIERR_NONE)
  371.     {
  372.         return FALSE;
  373.     }
  374.  
  375.     return TRUE;
  376. }
  377.  
  378. //===============================================================
  379. //  Name:   GetWorkingDirectory(hDb, szDirectory)
  380. //
  381. //  Input:  hDb         - Handle to the database
  382. //          szDirectory - Working directory
  383. //
  384. //  Return: Handle to the database, or zero if connection cannot
  385. //          be established.
  386. //
  387. //  Description:
  388. //          Try to connect to a database based on the data
  389. //          selected in the connection dialog box; display
  390. //          result in the static control.
  391. //================================================================
  392. DBIResult
  393. GetWorkingDirectory (hDBIDb hDb, pCHAR szDirectory)
  394. {
  395.     return DBIErr(DbiGetDirectory(hDb, FALSE, szDirectory));
  396. }
  397.  
  398. //===============================================================
  399. //  Name:   SetWorkingDirectory(hDb, szDirectory)
  400. //
  401. //  Input:  hDb         - Handle to the Database
  402. //          szDirectory - path to the directory
  403. //
  404. //  Return: DBIResult   - Success of the opperation
  405. //
  406. //  Description:
  407. //          This function is used to set the working directory of the
  408. //          database.
  409. //================================================================
  410. DBIResult
  411. SetWorkingDirectory (hDBIDb hDb, pCHAR szDirectory)
  412. {
  413.     return DBIErr(DbiSetDirectory(hDb, szDirectory));
  414. }
  415.  
  416. //===============================================================
  417. //  Name:   RegisterCallBack(hCur, ecbType, iClientData, iCbBufLen,
  418. //                           pCbBuf, pfCb);
  419. //
  420. //  Input:  hCur            - Handle to the cursor
  421. //          ecbType         - Type of the callback
  422. //          iClientData     - Client Data
  423. //          iCbBufLen       - Length of the buffer
  424. //          pCbBuf          - CallBack buffer
  425. //          pfCb            - Callback function
  426. //
  427. //  Return: Success of registering the callback
  428. //
  429. //  Description:
  430. //          This function is used to initialize callback functions.
  431. //================================================================
  432. DBIResult
  433. RegisterCallBack (hDBICur hCur, CBType ecbType, UINT32 iClientData,
  434.                   UINT16 iCbBufLen, pVOID pCbBuf, pfDBICallBack pfCb)
  435. {
  436.     DBIResult rslt; // Return value of IDAPI functions.
  437.  
  438.     rslt = DbiRegisterCallBack(hCur, ecbType, iClientData, iCbBufLen,
  439.                                pCbBuf, pfCb);
  440.     return rslt;
  441. }
  442.  
  443. //===============================================================
  444. //  Name:   IsStandardDatabase(hDb);
  445. //
  446. //  Input:  Handle to a database.
  447. //
  448. //  Return: TRUE if the database handle is open on a STANDARD database.
  449. //          FALSE if the database handle is open on a REMOTE database.
  450. //
  451. //  Description:
  452. //          Determines id the handle associated with the databases is
  453. //          connected to a STANDARD or REMORT database.
  454. //================================================================
  455. BOOL IsStandardDatabase(hDBIDb hDb)
  456. {
  457.     CHAR   DBType[DBIMAXMSGLEN];
  458.     // Get the type of database
  459.     DbiGetProp(hDb, dbDATABASETYPE, (pVOID)DBType, DBIMAXMSGLEN, NULL);
  460.     if (strcmpi(DBType, szCFGDBSTANDARD) == 0)
  461.         return TRUE;
  462.     else
  463.         return FALSE;
  464. }
  465.  
  466. //===============================================================
  467. //  Name:   GetErrorInformation(szOutputErrorString);
  468. //
  469. //  Input:  szOutputErrorString - Sting to contain the error string
  470. //
  471. //  Return: None
  472. //
  473. //  Description:
  474. //          This function will return information about an IDAPI error.
  475. //          Not that this needs to be called imediately after the error
  476. //          occurs.
  477. //================================================================
  478. void
  479. GetErrorInformation (char *szOutputErrorString)
  480. {
  481.     DBIErrInfo  ErrInfo;    // Error information.
  482.  
  483.     DbiGetErrorInfo(TRUE, &ErrInfo);
  484.  
  485.     sprintf(szOutputErrorString, "        ERROR -  Cat:Code = [%xh:%xh]"
  486.             "\r\n                 %s",
  487.             ErrCat(ErrInfo.iError), ErrCode(ErrInfo.iError),
  488.             ErrInfo.szErrCode);
  489.  
  490.     if (strcmp(ErrInfo.szContext1, ""))
  491.     {
  492.         strcat(szOutputErrorString, "\r\n                 ");
  493.         strcat(szOutputErrorString, ErrInfo.szContext1);
  494.     }
  495.     if (strcmp(ErrInfo.szContext2, ""))
  496.     {
  497.         strcat(szOutputErrorString, "\r\n                 ");
  498.         strcat(szOutputErrorString, ErrInfo.szContext2);
  499.     }
  500.     if (strcmp(ErrInfo.szContext3, ""))
  501.     {
  502.         strcat(szOutputErrorString, "\r\n                 ");
  503.         strcat(szOutputErrorString, ErrInfo.szContext3);
  504.     }
  505.     if (strcmp(ErrInfo.szContext4, ""))
  506.     {
  507.         strcat(szOutputErrorString, "\r\n                 ");
  508.         strcat(szOutputErrorString, ErrInfo.szContext4);
  509.     }
  510. }
  511.  
  512. //===============================================================
  513. //  Name:   CleanUpAnswer(hCur)
  514. //
  515. //  Input:  hCur    - Handle to the cursor
  516. //
  517. //  Return: Success of closing the cursor
  518. //
  519. //  Description:
  520. //          Close the cursor to the answer table and set the cursor
  521. //          to 0.
  522. //================================================================
  523. DBIResult
  524. CleanUpAnswer (hDBICur *hCur)
  525. {
  526.     DBIResult rslt;     // Return value from IDAPI functions
  527.  
  528.     if (*hCur)
  529.     {
  530.         rslt = DbiCloseCursor(hCur);
  531.         if (rslt == DBIERR_NONE)
  532.         {
  533.             *hCur = 0;
  534.         }
  535.     }
  536.  
  537.     return rslt;
  538. }
  539.  
  540.